package com.cc.dy.http.impl;

import cn.hutool.core.collection.CollUtil;
import com.cc.dy.api.response.DyResponse;
import com.cc.dy.executer.DyService;
import com.cc.dy.http.AbstractDyHttpClient;
import com.cc.dy.json.JsonSerializer;
import com.cc.dy.json.impl.FastJsonSerializer;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author chenChao 2023-09-08 13:43
 */
@Slf4j
public class OkHttpDyHttpClient extends AbstractDyHttpClient {

    public OkHttpDyHttpClient(DyService dyService) {
        super(dyService, new FastJsonSerializer());
    }

    public OkHttpDyHttpClient(DyService dyService, JsonSerializer jsonSerializer) {
        super(dyService, jsonSerializer);
    }

    /**
     * GET请求
     *
     * @param url     请求地址
     * @param headers 请求头
     * @param t       返回对象的类型
     * @return {@link T}
     */
    @Override
    public <T extends DyResponse> T getWithHeaders(String url, Map<String, String> headers, Class<T> t) {
        OkHttpClient client = new OkHttpClient().newBuilder()
                //设置连接超时时间
                .connectTimeout(dyService.getDyConfig().getHttpConnectionTimeout(), TimeUnit.SECONDS)
                //设置读取超时时间
                .readTimeout(dyService.getDyConfig().getHttpTimeout(), TimeUnit.SECONDS)
                .build();
        Request.Builder builder = new Request.Builder()
                .url(url)
                .get();
        if (CollUtil.isNotEmpty(headers)) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        try {
            log.info("GET请求，地址：{}，请求头：{}", url, headers);
            Response response = client.newCall(builder.build()).execute();
            log.info("GET响应，地址：{}，请求头：{}，结果：{}", url, headers, response);
            String responseStr = Objects.requireNonNull(response.body()).string();
            return this.getJsonSerializer().parseResponse(responseStr, t);
        } catch (IOException e) {
            log.error("GET请求异常:", e);
            throw new RuntimeException(e);
        }
    }


    /**
     * POST请求
     *
     * @param url        请求接口地址
     * @param headers    请求头
     * @param urlRequest 请求地址参数
     * @param params     请求对象
     * @param t          类型
     * @return {@link T}
     */
    @Override
    public <T extends DyResponse> T postWithHeaders(String url, Map<String, String> headers, Map<String, Object> urlRequest, Object params, Class<T> t) {
        if (CollUtil.isNotEmpty(urlRequest)) {
            url = urlJoinParams(url, urlRequest);
        }
        OkHttpClient client = new OkHttpClient().newBuilder()
                //设置连接超时时间
                .connectTimeout(dyService.getDyConfig().getHttpConnectionTimeout(), TimeUnit.SECONDS)
                //设置读取超时时间
                .readTimeout(dyService.getDyConfig().getHttpTimeout(), TimeUnit.SECONDS)
                .build();
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(mediaType, getJsonSerializer().toJson(params));
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(body);
        if (CollUtil.isNotEmpty(headers)) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        try {
            log.info("POST请求，地址：{}，请求头：{}, 参数：{}", url, headers, params);
            Response response = client.newCall(builder.build()).execute();
            String responseStr = Objects.requireNonNull(response.body()).string();
            log.info("POST响应，地址：{}，请求头：{}，参数：{}，结果：{}", url, headers, params, responseStr);
            return this.getJsonSerializer().parseResponse(responseStr, t);
        } catch (IOException e) {
            log.error("POST请求异常:", e);
            throw new RuntimeException(e);
        }
    }


}
